package br.urca.controller;

import java.io.IOException;
import java.io.StringReader;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;

import javax.inject.Inject;
import javax.transaction.Transactional;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.view.Results;
import br.urca.dao.AlunoIESDAO;
import br.urca.dao.PeriodoDAO;
import br.urca.dao.ProtocoloDAO;
import br.urca.dao.RequerimentoDAO;
import br.urca.dao.SolicitacaoDAO;
import br.urca.dao.StatusProtocoloDAO;
import br.urca.model.AlunoIES;
import br.urca.model.AlunoIESPK;
import br.urca.model.Periodo;
import br.urca.model.Protocolo;
import br.urca.model.ProtocoloPK;
import br.urca.model.Solicitacao;
import br.urca.model.SolicitacaoPK;
import br.urca.model.json.ProtocoloSolicitacao;
import br.urca.utils.Util;

@Controller
public class SolicitacaoController {
	
	public static final String TAG_RESPOSTA = "resposta";
	public static final String COD_COLACAO_GRAU = "04"; //Código da solicitação de colação de grau
	public static final String ORIGEM = "1"; //Aluno da instituição
	public static final String BANCO_TESEUS = "0";
	public static final String ISENTO = "N";
	public static final String SITUACAO_PENDENTE = "01";
	
	private SolicitacaoDAO mSolicitacaoDAO;
	private AlunoIESDAO mAlunoIESDAO;
	private ProtocoloDAO mProtocoloDAO;
	private PeriodoDAO mPeriodoDAO;
	private StatusProtocoloDAO mStatusProtocoloDAO;
	private RequerimentoDAO mRequerimentoDAO;
	private Result result;

	@Deprecated
	public SolicitacaoController() { }

	@Inject
	public SolicitacaoController(SolicitacaoDAO mSolicitacaoDAO,
			RequerimentoDAO mRequerimentoDAO, AlunoIESDAO mAlunoIESDAO,
			StatusProtocoloDAO mStatusProtocoloDAO, ProtocoloDAO mProtocoloDAO,
			PeriodoDAO mPeriodoDAO, Result result) {
		this.mSolicitacaoDAO = mSolicitacaoDAO;
		this.mProtocoloDAO = mProtocoloDAO;
		this.mPeriodoDAO = mPeriodoDAO;
		this.mAlunoIESDAO = mAlunoIESDAO;
		this.mStatusProtocoloDAO = mStatusProtocoloDAO;
		this.mRequerimentoDAO = mRequerimentoDAO;
		this.result = result;
	}
	
	@Get("/solicitacao/colacaograu/{key},{periodo},{matricula}")
	@Transactional
	public void solicitarColacaoGrau(String key, String periodo, String matricula) {
		Properties properties = new Properties();
		String mPeriodo = null;
		String mMatricula = null;
		String mKey = null;
		String numero = "";
		
		ProtocoloSolicitacao ps;
		
		if (periodo != null && matricula != null && key != null) {
			try {
				
				properties.load(new StringReader(periodo));
				mPeriodo = properties.getProperty("periodo");
				
				properties.load(new StringReader(matricula));
				mMatricula = properties.getProperty("matricula");
				
				properties.load(new StringReader(key));
				mKey = properties.getProperty("key");
				
				if (mKey.equalsIgnoreCase(Util.KEY_ALUNO_ONLINE)) {
				
					ps = consulta(key, periodo, matricula);
					
					if (ps == null) {
						ps = new ProtocoloSolicitacao();
						numero = mProtocoloDAO.ProximoNumero(mPeriodo);
						
						if (numero != null) {
							Protocolo prot = novoPrococolo(numero, mPeriodo);
							if (mProtocoloDAO.salvarProtocolo(prot)) {
								AlunoIES alunoIES = novoRegistroAlunoIES(prot, mMatricula);
								if (mAlunoIESDAO.salvarRegistro(alunoIES)) {
									Solicitacao soli = novaSolicitacao(prot);
									if (mSolicitacaoDAO.salvarSolicitacao(soli)) {
										
										ps.setMatricula(mMatricula);
										ps.setNumero(prot.getId().getNumero());
										ps.setPeriodo(prot.getId().getPeriodo());
										ps.setQuantidade(soli.getQuantidade());
										ps.setRequerimento(mRequerimentoDAO.getRequerimento(soli.getId().getCodRequerimento()).getDescricao());
										ps.setSituacao(soli.getSituacao().getDescricao());
										ps.setTaxaCobrada(alunoIES.getTemTaxa());
										ps.setValor(soli.getValor());	
										ps.setData(soli.getDataRec());
										
										this.result.use(Results.json()).from(ps, "resposta").serialize();								
									} else {
										throw new IOException("Não foi possível salvar o registro da solicitação!");
									}
								} else {
									throw new IOException("Não foi possível salvar o registro alunoIES!");
								}
							} else {
								throw new IOException("Não foi possível salvar o registro do protocolo!");
							}
						} else {
							throw new IOException("Não foi possível gerar o número do protocolo!");
						}
					} 							
				} else {
					throw new IOException("Chave de aplicativo inválida!");
				}
			} catch (IOException e) {
				this.result.use(Results.json()).from(new Object(), "resposta").serialize();
				e.printStackTrace();
			}
		} else {
			this.result.use(Results.json()).from(new Object(),"resposta").serialize();
		}
	}

	@Get("/consulta/solicitacao/{key},{periodo},{matricula}")
	public ProtocoloSolicitacao consulta(String key, String periodo, String matricula) {

		Solicitacao soli = null;
		Protocolo prot = null;
		AlunoIES alunoIES = null;
		ProtocoloSolicitacao ps = new ProtocoloSolicitacao();
		
		if (periodo != null && matricula != null) {

			Properties properties = new Properties();
			String mPeriodo = null;
			String mMatricula = null;
			String mKey = null;
			
			try {
				properties.load(new StringReader(periodo));
				mPeriodo = properties.getProperty("periodo");

				properties.load(new StringReader(matricula));
				mMatricula = properties.getProperty("matricula");
				
				properties.load(new StringReader(key));
				mKey = properties.getProperty("key");
				
				if (mKey.equalsIgnoreCase(Util.KEY_ALUNO_ONLINE)) {
				
					List<AlunoIES> mList = mAlunoIESDAO.getRegistros(mPeriodo, mMatricula);
					
					if (mList != null && !mList.isEmpty()) {
						for (AlunoIES a: mList) {						
							prot = mProtocoloDAO.getRegistro( 
									a.getId().getNumProtocolo(), a.getId().getPeriodo());
							if (prot.getFunRes().equalsIgnoreCase(COD_COLACAO_GRAU)) {
								alunoIES = a;
								break;
							}
						}
					}
	
					if (prot != null) {
						soli = mSolicitacaoDAO.getSolicitacao(prot.getId().getNumero(), prot.getId().getPeriodo(), COD_COLACAO_GRAU);
						if (soli != null) {
							ps.setMatricula(mMatricula);
							ps.setNumero(soli.getId().getNumProtocolo());
							ps.setPeriodo(prot.getId().getPeriodo());
							ps.setQuantidade(soli.getQuantidade());
							ps.setRequerimento(mRequerimentoDAO.getRequerimento(
									soli.getId().getCodRequerimento()).getDescricao());
							ps.setSituacao(soli.getSituacao().getDescricao());
							ps.setTaxaCobrada(alunoIES.getTemTaxa());
							ps.setValor(soli.getValor());
							ps.setData(soli.getDataRec());
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (ps.getNumero() != null) {
			this.result.use(Results.json()).from(ps, TAG_RESPOSTA).serialize();
			return ps;
		} else {
			this.result.use(Results.json()).from(new Object(), TAG_RESPOSTA)
					.serialize();
			return null;
		}
	}

	@Get("/consulta/periodopadrao")
	public void consultaPeriodoPadrao() {

		Periodo periodo = null;

		try {
			periodo = mPeriodoDAO.getPeriodoPadrao();
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (periodo != null) {
			this.result.use(Results.json()).from(periodo, TAG_RESPOSTA);
		} else {
			this.result.use(Results.json()).from(new Object(), TAG_RESPOSTA)
					.serialize();
		}
	}
	
	private Protocolo novoPrococolo(String numero, String periodo) {
		
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		Protocolo protocolo = new Protocolo();
		
		protocolo.setId(new ProtocoloPK(numero, periodo));
		protocolo.setDataEntrada(calendar.getTime());
		protocolo.setNume(null);
		protocolo.setFunRes(COD_COLACAO_GRAU);
		protocolo.setOrigem(ORIGEM);
		
		return protocolo;
		
	}
	
	private AlunoIES novoRegistroAlunoIES(Protocolo protocolo, String matricula) {
		
		AlunoIES alunoIES = new AlunoIES(new AlunoIESPK(protocolo.getId()
				.getNumero(), protocolo.getId().getPeriodo(), matricula),
				ISENTO, BANCO_TESEUS);		
		
		return alunoIES;
	}

	private Solicitacao novaSolicitacao(Protocolo protocolo) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		Solicitacao solicitacao = new Solicitacao();
		solicitacao.setDataRec(calendar.getTime());
		solicitacao.setId(new SolicitacaoPK(protocolo.getId().getPeriodo(), protocolo.getId().getNumero(), COD_COLACAO_GRAU));
		solicitacao.setSituacao(mStatusProtocoloDAO.getStatus(SITUACAO_PENDENTE));
		solicitacao.setValor(0.0);
		solicitacao.setQuantidade(1);
		solicitacao.setComplemento("Solicitação feita através do Aluno Online.");
		return solicitacao;
	}
	
}
